/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2008 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_ENCODER)

#include <trace_log.h>
#include "umc_avs_enc_compressor.h"
#include "umc_avs_sequence_header.h"
#include "umc_avs_pic.h"
#include "umc_avs_enc_me_estimator.h"

#include "umc_me_structures.h"
#include "umc_me.h"

static const Ipp16s MVRange[4*2]=
{
 /* x,      y*/
    256 /4 ,    128 /4,
    512 /4,     256 /4 ,
    2048/4,     512 /4 ,
    4096/4,     1024/4
};

namespace UMC
{

AVSME::AVSME(void)
{
    isAVSMEInit = false;
} // AVSME::AVSME(void)

AVSME::~AVSME(void)
{
    //m_avs_me.Close();
} // AVSME::~AVSME(void)

void AVSME::PrepareDisassembling(void)
{

} // void AVSCompressor::PrepareDisassembling(void)

void AVSME::EstimateIMacroBlocksRow(void)
{
    m_meCtx.MbIndex += m_meCtx.MbWidth;
} // void AVSME::EstimateIMacroBlocksRow(void)

void AVSME::EstimatePMacroBlocksRow(void)
{
    m_meCtx.MbIndex += m_meCtx.MbWidth;
} // void AVSME::EstimatePMacroBlocksRow(void)

void AVSME::EstimateBMacroBlocksRow(void)
{
    m_meCtx.MbIndex += m_meCtx.MbWidth;
} // void AVSME::EstimateBMacroBlocksRow(void)

Status AVSME::EstimateISlice(void)
{
    if (false == isAVSMEInit)
    {
        Ipp32s memSizeMe;
        //bool me_Res;
        memset(&MEParamsInit,0,sizeof(MEParamsInit));
        MEParamsInit.WidthMB        = m_meCtx.MbWidth;
        MEParamsInit.HeightMB       = m_meCtx.MbHeight;
        MEParamsInit.refPadding     = 32;
        MEParamsInit.MbPart         = ME_Mb16x16;

        ////MEParamsInit.SearchDirection = UMC::ME_ForwardSearch;
        MEParamsInit.SearchDirection = UMC::ME_BidirSearch;
        MEParamsInit.MaxNumOfFrame = 8;
        m_avs_me.Init(&MEParamsInit, NULL, memSizeMe);
        m_avs_me.Init(&MEParamsInit, (Ipp8u *)m_meCtx.m_pMeFrame[0], memSizeMe);
        isAVSMEInit = true;
    }

    // prepare MeFrame for future usage
    if (NULL == m_encCtx.m_pSlice->m_pPic->m_pMeFrame)
    {
        //(m_encCtx.m_pSlice->m_pPic->m_pRefs[0][0])->m_pMeFrame = NULL;
        m_encCtx.m_pSlice->m_pPic->m_pMeFrame = m_meCtx.m_pMeFrame[0];
    }

    MeFrame *currMeFrame = m_encCtx.m_pSlice->m_pPic->m_pMeFrame;
    //MeFrame *currMeFrame = m_meCtx.m_pMeFrame[0];

    Ipp32s maxNumMb = m_meCtx.MbWidth * m_meCtx.MbHeight;
    MeMB *pCurrMeMB = currMeFrame->MBs;
    for (Ipp32s i = 0; i < maxNumMb; i++)
    {
        pCurrMeMB->MbPart = ME_Mb16x16;
        pCurrMeMB->MbType = ME_MbIntra;
        pCurrMeMB += 1;
    }

    m_meCtx.MbIndex = m_meCtx.MbWidth * m_meCtx.MbHeight;
    return UMC_OK;
} // Status AVSME::EstimateISlice

Status AVSME::EstimatePSlice(void)
{
    Status umcRes;
    // set current and reference frames for me
    MeFrame *refMeFrame, *currMeFrame /*, *refMeFrame1 */;
    //refMeFrame = &MEParamsInit.pFrames[0];
    //currMeFrame = &MEParamsInit.pFrames[1];
    //m_pMeFRame
    //refMeFrame = m_meCtx.m_pMeFrame[0];
    refMeFrame = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pMeFrame;
    //if ((NULL != (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][1])) &&
    //    (   (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0]) != 
    //        (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][1]) ))
    //{
    //        refMeFrame1 = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][1])->m_pMeFrame;
    //}
    //currMeFrame = m_meCtx.m_pMeFrame[1];
    currMeFrame = m_encCtx.m_pSlice->m_pPic->m_pMeFrame;
    
    currMeFrame->WidthMB  = refMeFrame->WidthMB = /*refMeFrame1->WidthMB = */  m_meCtx.MbWidth;
    currMeFrame->HeightMB = refMeFrame->HeightMB = /*refMeFrame1->HeightMB = */ m_meCtx.MbHeight;
    //currMeFrame->ptr[0] =  (Ipp8u *) m_meCtx.m_pSrcPlanes8u[0];
    currMeFrame->SrcPlane.chroma = false;
    currMeFrame->SrcPlane.ptr[0] = currMeFrame->plane[0].ptr[0] = 
                    (Ipp8u *)m_meCtx.m_pSrcPlanes8u[0];
    // chroma planes
    currMeFrame->SrcPlane.ptr[1] = currMeFrame->plane[0].ptr[1] = 
                    (Ipp8u *)m_meCtx.m_pSrcPlanes8u[1];
    currMeFrame->SrcPlane.ptr[2] = currMeFrame->plane[0].ptr[2] = 
                    (Ipp8u *)m_meCtx.m_pSrcPlanes8u[2];
    //refMeFrame.ptr[0] = (Ipp8u *) ((m_pRefs[AVS_FORWARD][0])->m_pRefPlanes8u[0]);
    //refMeFrame->ptr[0] = (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pRefPlanes8u[0]);
    //refMeFrame->ptr[0] = (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pSrcPlanes8u[0]);
    refMeFrame->RecPlane.ptr[0] = refMeFrame->SrcPlane.ptr[0] = refMeFrame->plane[0].ptr[0] =
        (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pPlanes8u[0]);
    refMeFrame->RecPlane.ptr[1] = refMeFrame->SrcPlane.ptr[1] = refMeFrame->plane[0].ptr[1] =
        (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pPlanes8u[1]);
    refMeFrame->RecPlane.ptr[2] = refMeFrame->SrcPlane.ptr[2] = refMeFrame->plane[0].ptr[2] =
        (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pPlanes8u[2]);

    //refMeFrame1->SrcPlane.ptr[0] = refMeFrame1->plane[0].ptr[0] =
    //    (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][1])->m_pPlanes8u[0]);
    
    currMeFrame->plane[0].step[0] = currMeFrame->SrcPlane.step[0] =
    refMeFrame->plane[0].step[0] = refMeFrame->SrcPlane.step[0] =
    /*refMeFrame1->plane[0].step[0] = refMeFrame1->SrcPlane.step[0] = */m_meCtx.m_iPitch;
    currMeFrame->plane[0].step[1] = currMeFrame->SrcPlane.step[1] =
    currMeFrame->plane[0].step[2] = currMeFrame->SrcPlane.step[2] =
    refMeFrame->plane[0].step[1] = refMeFrame->SrcPlane.step[1] =
    refMeFrame->plane[0].step[2] = refMeFrame->SrcPlane.step[2] =
    /*refMeFrame1->plane[0].step[0] = refMeFrame1->SrcPlane.step[0] = */m_meCtx.m_iPitch;
    refMeFrame->RecPlane.step[0] = refMeFrame->RecPlane.step[1] = 
        refMeFrame->RecPlane.step[2] = m_meCtx.m_iPitch;

    currMeFrame->type = ME_FrmFrw;// 1 means ME_FrmFrw
    //refMeFrame->type = ME_FrmFrw; //??? 0 means ME_FrmIntra
    //refMeFrame1->type = ME_FrmFrw;

    // set raw ME params
    //UMC::MeParams *MEParams  = new MeParams();
    MEParams.pSrc = currMeFrame;

    MEParams.pRefF[0] = refMeFrame;
    //MEParams.pRefF[1] = refMeFrame1;
    //MEParams.FRefFramesNum = 2;

    // just copy params from VC1
    MEParams.Interpolation = ME_AVS_Luma;
    MEParams.SearchDirection =  UMC::ME_ForwardSearch;
    MEParams.PixelType = UMC::ME_QuarterPixel;
    //MEParams.PixelType = UMC::ME_HalfPixel;
    //MEParams.PixelType = UMC::ME_IntegerPixel;
    MEParams.MbPart = ME_Mb16x16;
    //MEParams.MbPart = ME_Mb8x8;
    //MEParams.MbPart = ME_Mb16x16|ME_Mb8x8;
    // may be 0-127; should be set via par-file
    MEParams.SetSearchSpeed(m_pAVSCompressorParams->m_uiMESearchSpeed);
    MEParams.PredictionType = ME_AVS;

    MEParams.PicRange.top_left.x       = 0;
    MEParams.PicRange.top_left.y       = 0;
    MEParams.PicRange.bottom_right.x   = m_meCtx.MbWidth * 16  ;
    MEParams.PicRange.bottom_right.y   = m_meCtx.MbHeight * 16 ;

    MEParams.FirstMB = 0;
    MEParams.LastMB = m_meCtx.MbWidth * m_meCtx.MbHeight -1;

    MEParams.SearchRange.x             = 64;///4;//MVRange[/*2*m_InitPicParam.uiMVRangeIndex = 0*/ 0];
    MEParams.SearchRange.y             = 32;///4;//MVRange[/*2*m_InitPicParam.uiMVRangeIndex = 0*/1];
    MEParams.SkippedMetrics            = UMC::ME_Sad;
    MEParams.CostMetric                = UMC::ME_Sad;
    MEParams.Quant                     = m_meCtx.PreviousQP;
    if (m_pAVSCompressorParams->m_bUseMeFeedback)
    {
        MEParams.ProcessSkipped = true;
        MEParams.UpdateFeedback = true;
        MEParams.UseFeedback = true;
        MEParams.UseFastFeedback = true;
    }
    //MEParams.use
    m_avs_me.SetBlockDist(m_encCtx.m_pSlice->m_pPic->m_blockDist, 
                   sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    m_avs_me.SetBlockIdx(m_encCtx.m_pSlice->m_pPic->m_distIdx,
                  sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    //memcpy(m_avs_me.m_blockDist,m_encCtx.m_pSlice->m_pPic->m_blockDist,
    //                     sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist)); 
    //memcpy(m_avs_me.m_distIdx,m_encCtx.m_pSlice->m_pPic->m_distIdx,
    //                   sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));

    umcRes = m_avs_me.EstimateFrame(&MEParams);
    
    Ipp32s maxNumMb = m_meCtx.MbWidth * m_meCtx.MbHeight;
    //AVS_MB_INFO *pCurrMbInfo = m_meCtx.m_pMBInfo;
    AVS_MB_INFO *pCurrMbInfo = m_encCtx.m_pMBInfo;
    MeMB *pCurrMeMB = MEParams.pSrc->MBs;

    for (Ipp32s i = 0; i < maxNumMb; i++)
    {
        //
        //pCurrMbInfo->divType = (eAVSDivBlockType) (pCurrMeMB->MbPart -1) ;
        // reset macroblock info
        memset(pCurrMbInfo, 0, sizeof(AVS_MB_INFO));
        // by default
        pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
        pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredForward;

        if (ME_MbIntra == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = I_8x8;
            pCurrMbInfo->MvNum = 0;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredIntra;
        }
        else if (ME_MbFrwSkipped == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = P_Skip;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 0;
            pCurrMbInfo->MbCBP = 0;
        }
        //else if (ME_Mb8x8 == pCurrMeMB->MbPart)
        //{
        //    pCurrMbInfo->MbType = P_8x8;
        //    pCurrMbInfo->divType = Div_8x8;
        //    pCurrMbInfo->MvNum = 4;
        //}
        else //16x16 by default, 16x8 and 8x16 doesn't support by ME
        {
            pCurrMbInfo->MbType = P_16x16;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 1;
        }
        // copy vectors
        pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
        pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
        pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
        pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
        pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
        pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
        pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
        pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;
        // logs for debug
        if ( 0 == i)
        {
            WRITE_TRACE_LOG(_vec_me_tst, "Frame num is  ", m_meCtx.m_pPicHeader->picture_distance - 1);
        }

        WRITE_TRACE_LOG_MB_TITLE(_vec_me_tst, i /*MbIndex*/, m_meCtx.MbWidth, m_meCtx.MbHeight, 0 == m_meCtx.m_pPicHeader->progressive_frame);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][0].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][0].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][1].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][1].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][2].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][2].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][3].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][3].vector.y);

        pCurrMbInfo += 1;
        pCurrMeMB += 1;
    }
    
    //m_meCtx.MbMeIndex += m_meCtx.MbWidth;
    // so slice done
    m_meCtx.MbIndex = maxNumMb;
    
    // process feedback
    if ( true == MEParams.UseFeedback)
        m_avs_me.ProcessFeedback(&MEParams); 

    return UMC_OK;
} // void AVSME::EstimatePMacroBlocksRow(void)

Status AVSME::EstimateBSlice(void)
{
    Status umcRes = 0;

    MeFrame *refFwdMeFrame, *refBkdMeFrame, *currMeFrame;
    //currMeFrame = &MEParamsInit.pFrames[0];
    //refFwdMeFrame = &MEParamsInit.pFrames[1];
    //refBkdMeFrame = &MEParamsInit.pFrames[2];
    refFwdMeFrame = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pMeFrame;
    refBkdMeFrame = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])->m_pMeFrame;
    //currMeFrame = m_meCtx.m_pMeFrame[1];
    currMeFrame = m_encCtx.m_pSlice->m_pPic->m_pMeFrame;


    currMeFrame->WidthMB = refBkdMeFrame->WidthMB = refFwdMeFrame->WidthMB =  m_meCtx.MbWidth;
    currMeFrame->HeightMB = refBkdMeFrame->HeightMB = refFwdMeFrame->HeightMB = m_meCtx.MbHeight;
    //currMeFrame->ptr[0] =  (Ipp8u *) m_meCtx.m_pSrcPlanes8u[0];
    currMeFrame->SrcPlane.chroma = false;
    currMeFrame->SrcPlane.ptr[0] = currMeFrame->plane[0].ptr[0] =
        (Ipp8u *)m_meCtx.m_pSrcPlanes8u[0];
    //currMeFrame->step[0] =  refBkdMeFrame->step[0] = refFwdMeFrame->step[0] = m_meCtx.m_iPitch;
    //refFwdMeFrame.ptr[0] = (Ipp8u *) ((m_pRefs[AVS_FORWARD][0])->m_pRefPlanes8u[0]);
    //refFwdMeFrame->ptr[0] = (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pRefPlanes8u[0]);
    //refFwdMeFrame->ptr[0] = (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pPlanes8u[0]);
    //refBkdMeFrame->ptr[0] = (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])->m_pPlanes8u[0]);
    refFwdMeFrame->SrcPlane.ptr[0] = refFwdMeFrame->plane[0].ptr[0] =
        (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_pPlanes8u[0]);
    refBkdMeFrame->SrcPlane.ptr[0] = refBkdMeFrame->plane[0].ptr[0] =
        (Ipp8u *) ((m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])->m_pPlanes8u[0]);
    refFwdMeFrame->SrcPlane.step[0] = currMeFrame->SrcPlane.step[0] =
         refBkdMeFrame->SrcPlane.step[0] = m_meCtx.m_iPitch;
    refFwdMeFrame->plane[0].step[0] = currMeFrame->plane[0].step[0] =
         refBkdMeFrame->plane[0].step[0] = m_meCtx.m_iPitch;

    currMeFrame->type = ME_FrmFrw;// 1 means ME_FrmFrw
    refFwdMeFrame->type = ME_FrmFrw; //??? 0 means ME_FrmIntra
    refBkdMeFrame->type = ME_FrmBidir; //???  ME_FrmBidir
    // to set indexes
    memcpy(currMeFrame->m_blockDist, m_encCtx.m_pSlice->m_pPic->m_blockDist,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    memcpy(currMeFrame->m_distIdx, m_encCtx.m_pSlice->m_pPic->m_distIdx,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    //
    memcpy(refFwdMeFrame->m_blockDist,(m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_blockDist,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    memcpy(refFwdMeFrame->m_distIdx, (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])->m_distIdx,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    memcpy(refBkdMeFrame->m_blockDist,(m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])->m_blockDist,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    memcpy(refBkdMeFrame->m_distIdx, (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])->m_distIdx,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    currMeFrame->picture_distance = m_encCtx.m_pPicHeader->picture_distance;

    // set raw ME params
    //UMC::MeParams *MEParams  = new MeParams();
    MEParams.pSrc = currMeFrame;

    MEParams.pRefF[0] = refFwdMeFrame;
    MEParams.pRefB[0] = refBkdMeFrame;
    MEParams.FRefFramesNum = 1;
    MEParams.BRefFramesNum = 1;

    // just copy params from VC1
    MEParams.Interpolation = UMC::ME_VC1_Bilinear;
    //MEParams.SearchDirection =  UMC::ME_ForwardSearch;
    MEParams.SearchDirection =  UMC::ME_BidirSearch;
    //MEParams.PixelType = UMC::ME_QuarterPixel;
    MEParams.PixelType = UMC::ME_IntegerPixel;
    MEParams.MbPart = ME_Mb16x16;
    //MEParams.MbPart = ME_Mb16x16 | ME_Mb8x8;
    //MEParams.MbPart = ME_Mb8x8;
    // may be 0-127; should be set via par-file 
    MEParams.SetSearchSpeed(m_pAVSCompressorParams->m_uiMESearchSpeed);
    //MEParams.PredictionType = ME_VC1;
    MEParams.PredictionType = ME_AVS;

    MEParams.PicRange.top_left.x       = 0;
    MEParams.PicRange.top_left.y       = 0;
    MEParams.PicRange.bottom_right.x   = m_meCtx.MbWidth * 16  ;
    MEParams.PicRange.bottom_right.y   = m_meCtx.MbHeight * 16 ;

    //MEParams.width   = m_meCtx.MbWidth * 16;
    //MEParams.height  = m_meCtx.MbHeight * 16;
    //MEParams.padding = 16;
    MEParams.FirstMB = 0;
    MEParams.LastMB = m_meCtx.MbWidth * m_meCtx.MbHeight -1;


    MEParams.SearchRange.x             = 64;///4;//MVRange[/*2*m_InitPicParam.uiMVRangeIndex = 0*/ 0];
    MEParams.SearchRange.y             = 32;///4;//MVRange[/*2*m_InitPicParam.uiMVRangeIndex = 0*/1];
    MEParams.SkippedMetrics            = UMC::ME_Sad;
    MEParams.CostMetric                = UMC::ME_Sad;
    MEParams.Quant                     = m_meCtx.PreviousQP;
    MEParams.ProcessSkipped = true;
    MEParams.UpdateFeedback = false;
    MEParams.UseFeedback = false;
    MEParams.ProcessDirect = true;
    MEParams.UseDownSampledImageForSearch = true;
    //m_avs_me.SetBlockDist(m_encCtx.m_pSlice->m_pPic->m_blockDist, 
    //               sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    //m_avs_me.SetBlockIdx(m_encCtx.m_pSlice->m_pPic->m_distIdx,
    //              sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    memcpy(m_avs_me.m_blockDist,m_encCtx.m_pSlice->m_pPic->m_blockDist,
                         sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist)); 
    memcpy(m_avs_me.m_distIdx,m_encCtx.m_pSlice->m_pPic->m_distIdx,
                        sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    //memcpy(m_avs_me.m_blockDist,m_encCtx.m_pSlice->m_pPic->m_blockDist,
    //                     sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    //memcpy(m_avs_me.m_distIdx,m_encCtx.m_pSlice->m_pPic->m_distIdx,
    //                    sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));

    // Reconstruct Direct Motion Vectors in the current BSlice
    ReconstructDirectMotionVectors();

    umcRes = m_avs_me.EstimateFrame(&MEParams);

    Ipp32s maxNumMb = m_meCtx.MbWidth * m_meCtx.MbHeight;
    //AVS_MB_INFO *pCurrMbInfo = m_meCtx.m_pMBInfo;
    AVS_MB_INFO *pCurrMbInfo = m_encCtx.m_pMBInfo;
    MeMB *pCurrMeMB = MEParams.pSrc->MBs;

    for (Ipp32s i = 0; i < maxNumMb; i++)
    {
        //
        // pCurrMbInfo->divType = (eAVSDivBlockType) (pCurrMeMB->MbPart -1) ;
        // reset macroblock info
        memset(pCurrMbInfo, 0, sizeof(AVS_MB_INFO));
        // by default
        //pCurrMbInfo->divType = Div_16x16;
        //pCurrMbInfo->MvNum = 1;
        if (ME_MbIntra == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = I_8x8;
            pCurrMbInfo->MvNum = 0;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredIntra;
        }
        else if (ME_MbBkw == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = B_Bck_16x16;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 1;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredBackward;

            pCurrMbInfo->mv[0][0].scalar = pCurrMbInfo->mv[0][1].scalar =
            pCurrMbInfo->mv[0][2].scalar = pCurrMbInfo->mv[0][3].scalar = 0;
            pCurrMbInfo->mv[1][0].vector.x = (pCurrMeMB->MV[1][0].x);// >>2;
            pCurrMbInfo->mv[1][0].vector.y = (pCurrMeMB->MV[1][0].y);// >>2;
            pCurrMbInfo->mv[1][1].vector.x = (pCurrMeMB->MV[1][1].x);// >>2;
            pCurrMbInfo->mv[1][1].vector.y = (pCurrMeMB->MV[1][1].y);// >>2;
            pCurrMbInfo->mv[1][2].vector.x = (pCurrMeMB->MV[1][2].x);// >>2;
            pCurrMbInfo->mv[1][2].vector.y = (pCurrMeMB->MV[1][2].y);// >>2;
            pCurrMbInfo->mv[1][3].vector.x = (pCurrMeMB->MV[1][3].x);// >>2;
            pCurrMbInfo->mv[1][3].vector.y = (pCurrMeMB->MV[1][3].y);// >>2;

        }
        else if (ME_MbBidir == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = B_Sym_16x16;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 1;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredBiDir;
            pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
            pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
            pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
            pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
            pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
            pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
            pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
            pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;

            pCurrMbInfo->mv[1][0].vector.x = (pCurrMeMB->MV[1][0].x);// >>2;
            pCurrMbInfo->mv[1][0].vector.y = (pCurrMeMB->MV[1][0].y);// >>2;
            pCurrMbInfo->mv[1][1].vector.x = (pCurrMeMB->MV[1][1].x);// >>2;
            pCurrMbInfo->mv[1][1].vector.y = (pCurrMeMB->MV[1][1].y);// >>2;
            pCurrMbInfo->mv[1][2].vector.x = (pCurrMeMB->MV[1][2].x);// >>2;
            pCurrMbInfo->mv[1][2].vector.y = (pCurrMeMB->MV[1][2].y);// >>2;
            pCurrMbInfo->mv[1][3].vector.x = (pCurrMeMB->MV[1][3].x);// >>2;
            pCurrMbInfo->mv[1][3].vector.y = (pCurrMeMB->MV[1][3].y);// >>2;
        }
        else if ((ME_MbFrwSkipped == pCurrMeMB->MbType) ||
                 (ME_MbBkwSkipped == pCurrMeMB->MbType) ||
                 (ME_MbBidirSkipped == pCurrMeMB->MbType) ||
                 (ME_MbDirectSkipped == pCurrMeMB->MbType) /*||
                 (ME_MbDirect == pCurrMeMB->MbType)*/)
        {
            pCurrMbInfo->MbType = B_Skip;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 0;
            pCurrMbInfo->MbCBP = 0;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredBiDir;
        }
        else if (ME_MbDirect == pCurrMeMB->MbType)
        {
            pCurrMbInfo->MbType = B_Direct_16x16;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 0;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredBiDir;
            pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
            pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
            pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
            pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
            pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
            pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
            pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
            pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;

            pCurrMbInfo->mv[1][0].vector.x = (pCurrMeMB->MV[1][0].x);// >>2;
            pCurrMbInfo->mv[1][0].vector.y = (pCurrMeMB->MV[1][0].y);// >>2;
            pCurrMbInfo->mv[1][1].vector.x = (pCurrMeMB->MV[1][1].x);// >>2;
            pCurrMbInfo->mv[1][1].vector.y = (pCurrMeMB->MV[1][1].y);// >>2;
            pCurrMbInfo->mv[1][2].vector.x = (pCurrMeMB->MV[1][2].x);// >>2;
            pCurrMbInfo->mv[1][2].vector.y = (pCurrMeMB->MV[1][2].y);// >>2;
            pCurrMbInfo->mv[1][3].vector.x = (pCurrMeMB->MV[1][3].x);// >>2;
            pCurrMbInfo->mv[1][3].vector.y = (pCurrMeMB->MV[1][3].y);// >>2;

        }
        //else if (ME_Mb8x8 == pCurrMeMB->MbPart)
        //{
        //    pCurrMbInfo->MbType = B_8x8;
        //    pCurrMbInfo->divType = Div_8x8;
        //    for (Ipp32s j = 0; j < 4; j++)
        //    {
        //        switch (pCurrMeMB->BlockType[j])
        //        {
        //            case ME_BlockSkipped:
        //                 pCurrMbInfo->predType[j] = PredDirect;
        //                 break;
        //            case ME_BlockBkw:
        //                 pCurrMbInfo->predType[j] = PredBackward;
        //                 break;
        //            case ME_BlockBidir:
        //                 pCurrMbInfo->predType[j] = PredBiDir;
        //                 break;
        //            case ME_BlockFrw:
        //            case ME_BlockIntra:
        //            case ME_BlockOutOfBound:
        //                 pCurrMbInfo->predType[j] = PredForward;
        //                 break;
        //        }
        //    }
        //    pCurrMbInfo->MvNum = 4;
        //    pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
        //    pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
        //    pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
        //    pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
        //    pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
        //    pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
        //    pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
        //    pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;

        //    pCurrMbInfo->mv[1][0].vector.x = (pCurrMeMB->MV[1][0].x);// >>2;
        //    pCurrMbInfo->mv[1][0].vector.y = (pCurrMeMB->MV[1][0].y);// >>2;
        //    pCurrMbInfo->mv[1][1].vector.x = (pCurrMeMB->MV[1][1].x);// >>2;
        //    pCurrMbInfo->mv[1][1].vector.y = (pCurrMeMB->MV[1][1].y);// >>2;
        //    pCurrMbInfo->mv[1][2].vector.x = (pCurrMeMB->MV[1][2].x);// >>2;
        //    pCurrMbInfo->mv[1][2].vector.y = (pCurrMeMB->MV[1][2].y);// >>2;
        //    pCurrMbInfo->mv[1][3].vector.x = (pCurrMeMB->MV[1][3].x);// >>2;
        //    pCurrMbInfo->mv[1][3].vector.y = (pCurrMeMB->MV[1][3].y);// >>2;
        //
        //}
        else //if (ME_MbFrw == pCurrMeMB->MbType) // by default
        {
            pCurrMbInfo->MbType = B_Fwd_16x16;
            pCurrMbInfo->divType = Div_16x16;
            pCurrMbInfo->MvNum = 1;
            pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
            pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredForward;
            pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
            pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
            pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
            pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
            pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
            pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
            pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
            pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;
            pCurrMbInfo->mv[1][0].scalar = pCurrMbInfo->mv[1][1].scalar =
            pCurrMbInfo->mv[1][2].scalar = pCurrMbInfo->mv[1][3].scalar = 0;

        }

        //pCurrMbInfo->divType = Div_16x16;
        //pCurrMbInfo->MvNum = 1;
        //pCurrMbInfo->MvNum = 4;
        //pCurrMbInfo->mv[0][0].vector.x = (pCurrMeMB->MV[0][0].x);// >>2;
        //pCurrMbInfo->mv[0][0].vector.y = (pCurrMeMB->MV[0][0].y);// >>2;
        //pCurrMbInfo->mv[0][1].vector.x = (pCurrMeMB->MV[0][1].x);// >>2;
        //pCurrMbInfo->mv[0][1].vector.y = (pCurrMeMB->MV[0][1].y);// >>2;
        //pCurrMbInfo->mv[0][2].vector.x = (pCurrMeMB->MV[0][2].x);// >>2;
        //pCurrMbInfo->mv[0][2].vector.y = (pCurrMeMB->MV[0][2].y);// >>2;
        //pCurrMbInfo->mv[0][3].vector.x = (pCurrMeMB->MV[0][3].x);// >>2;
        //pCurrMbInfo->mv[0][3].vector.y = (pCurrMeMB->MV[0][3].y);// >>2;

        //pCurrMbInfo->mv[1][0].vector.x = (pCurrMeMB->MV[1][0].x);// >>2;
        //pCurrMbInfo->mv[1][0].vector.y = (pCurrMeMB->MV[1][0].y);// >>2;
        //pCurrMbInfo->mv[1][1].vector.x = (pCurrMeMB->MV[1][1].x);// >>2;
        //pCurrMbInfo->mv[1][1].vector.y = (pCurrMeMB->MV[1][1].y);// >>2;
        //pCurrMbInfo->mv[1][2].vector.x = (pCurrMeMB->MV[1][2].x);// >>2;
        //pCurrMbInfo->mv[1][2].vector.y = (pCurrMeMB->MV[1][2].y);// >>2;
        //pCurrMbInfo->mv[1][3].vector.x = (pCurrMeMB->MV[1][3].x);// >>2;
        //pCurrMbInfo->mv[1][3].vector.y = (pCurrMeMB->MV[1][3].y);// >>2;
        //}

        //pCurrMbInfo->predType[0] = pCurrMbInfo->predType[1] =
        //pCurrMbInfo->predType[2] = pCurrMbInfo->predType[3] = PredForward;

                // logs for debug
        if ( 0 == i)
        {
            WRITE_TRACE_LOG(_vec_me_tst, "Frame num is  ", m_meCtx.m_pPicHeader->picture_distance - 1);
        }

        WRITE_TRACE_LOG_MB_TITLE(_vec_me_tst, i /*MbIndex*/, m_meCtx.MbWidth, m_meCtx.MbHeight, 0 == m_meCtx.m_pPicHeader->progressive_frame);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][0].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][0].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][1].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][1].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][2].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][2].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector X", pCurrMbInfo->mv[AVS_FORWARD][3].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "FW motion vector Y", pCurrMbInfo->mv[AVS_FORWARD][3].vector.y);

        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector X", m_pMbInfo->mv[AVS_BACKWARD][0].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector Y", m_pMbInfo->mv[AVS_BACKWARD][0].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector X", m_pMbInfo->mv[AVS_BACKWARD][1].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector Y", m_pMbInfo->mv[AVS_BACKWARD][1].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector X", m_pMbInfo->mv[AVS_BACKWARD][2].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector Y", m_pMbInfo->mv[AVS_BACKWARD][2].vector.y);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector X", m_pMbInfo->mv[AVS_BACKWARD][3].vector.x);
        WRITE_TRACE_LOG(_vec_me_tst, "BW motion vector Y", m_pMbInfo->mv[AVS_BACKWARD][3].vector.y);
        
        pCurrMbInfo += 1;
        pCurrMeMB += 1;
    }

    //m_meCtx.MbMeIndex += m_meCtx.MbWidth;
    // slice done
    m_meCtx.MbIndex = maxNumMb;
    return UMC_OK;
} // Status AVSME::EstimateBSlice(void)

void AVSME::ReconstructDirectMotionVectors(void)
{
    //MeFrame *currMeFrame = m_encCtx.m_pSlice->m_pPic->m_pMeFrame;
    //this->SetDecodingContext(m_encCtx);
    memcpy(m_pRefs,m_encCtx.m_pSlice->m_pPic->m_pRefs, sizeof(m_pRefs));
    memcpy(this->m_blockDist,m_encCtx.m_pSlice->m_pPic->m_blockDist,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_blockDist));
    memcpy(this->m_distIdx,m_encCtx.m_pSlice->m_pPic->m_distIdx,
            sizeof(m_encCtx.m_pSlice->m_pPic->m_distIdx));
    MbIndex = m_encCtx.MbIndex;
    m_decCtx.MbX = m_encCtx.MbX;
    m_decCtx.MbY = m_encCtx.MbY;
    m_decCtx.MbFirst = m_encCtx.MbFirst;
    m_decCtx.MbLast = m_encCtx.MbLast;
    m_decCtx.MbHeight = m_encCtx.MbHeight;
    m_decCtx.MbWidth = m_encCtx.MbWidth;
    m_pMbInfo = m_encCtx.m_pMBInfo;
    MeMV *pCurrFwdMVDirect = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_FORWARD][0])
                                                            ->m_pMeFrame->MVDirect;
    MeMV *pCurrBkdMVDirect = (m_encCtx.m_pSlice->m_pPic->m_pRefs[AVS_BACKWARD][0])
                                                                ->m_pMeFrame->MVDirect;
    //
    for (Ipp32s i = m_decCtx.MbFirst; i < m_decCtx.MbLast; i++)
    {
        // set MBs edges
        Ipp32s widthMB = m_decCtx.MbWidth;
        if(0 == m_decCtx.MbX)
            m_pMbInfoLeft = NULL;
        else
            m_pMbInfoLeft = m_encCtx.m_pMBInfo + (m_decCtx.MbX -1) + (m_decCtx.MbY)*widthMB;

        if(0 == m_decCtx.MbY)
        {
            m_pMbInfoTop = m_pMbInfoTopRight = m_pMbInfoTopLeft = NULL;
        }
        else
        {
            if (m_pMbInfoLeft) //( 1 <= m_decCtx.MbX)
            {
                m_pMbInfoTopLeft = m_encCtx.m_pMBInfo + (m_decCtx.MbX -1) + (m_decCtx.MbY-1)*widthMB;
                m_pMbInfoTop = m_encCtx.m_pMBInfo + (m_decCtx.MbX) + (m_decCtx.MbY-1)*widthMB;
            }
            if(m_decCtx.MbX == widthMB - 1)
                m_pMbInfoTopRight = NULL;
            else
                m_pMbInfoTopRight = m_encCtx.m_pMBInfo + (m_decCtx.MbX +1) + (m_decCtx.MbY -1 )*widthMB;
        }
        //and finally set current block

        ReconstructMotionVectorsBSliceDirect();
        // only for 16x16 
        pCurrFwdMVDirect->x = m_pMbInfo->mv[0][0].vector.x;
        pCurrFwdMVDirect->y = m_pMbInfo->mv[0][0].vector.y;
        pCurrBkdMVDirect->x = m_pMbInfo->mv[1][0].vector.x;
        pCurrBkdMVDirect->y = m_pMbInfo->mv[1][0].vector.y;
        pCurrFwdMVDirect++;
        pCurrBkdMVDirect++;
        MbIndex++;
    }

} // void AVSME::ReconstructDirectMotionVectors(void)


void AVSME::AdvanceDisassembling(void)
{
    // update plane pointers
    if (1 == m_meCtx.m_pSeqHeader->sample_precission)
    {
        // advance luminance pointer
        m_meCtx.m_pSrcPlanes8u[0] += 16;

        // advance chrominance pointer
        m_meCtx.m_pSrcPlanes8u[1] += 8;
        m_meCtx.m_pSrcPlanes8u[2] += 8;
    }

    // update macroblock position
    m_meCtx.MbX += 1;

} // void AVSCompressor::AdvanceDisassembling(void)

//Status AVSME::SetMEParams(MeInitParams *MEParamsInit)
//Status AVSME::SetMEParams(void)
//{
//    MEParamsInit.WidthMB          = m_meCtx.MbWidth;
//    MEParamsInit.HeightMB         = m_meCtx.MbHeight;
//    MEParamsInit.refPadding     = 32;
//    MEParamsInit.MbPart         = ME_Mb16x16;
//
//    //MEParamsInit.SearchDirection = UMC::ME_ForwardSearch;
//    MEParamsInit.SearchDirection = UMC::ME_BidirSearch;
//    MEParamsInit.MaxNumOfFrame = 4;
//
//    bool res = m_avs_me.Init(&MEParamsInit);//, m_pMEBuffer, memSize);
//    if(res)
//    {
//        isAVSMEInit = true;
//        return UMC_OK;
//    }
//    else
//        return UMC_ERR_INIT;
//
//} // void AVSME::SetMEParams(MeInitParams MEParamsInit)

//Status AVSME::SetMEFrames(void)
//{
//    return UMC_OK;
//} // Status AVSME::SetMEFrames(void)

void AVSME::FinalizeDisassembling(void)
{
    // update variables
    m_meCtx.MbIndex += m_meCtx.MbWidth;
    m_meCtx.m_pMBInfo += m_meCtx.MbWidth;
    m_meCtx.MbX = 0;
    m_meCtx.MbY = m_meCtx.MbY + 1;

    // update pointers to the video planes
    if (1 == m_meCtx.m_pSeqHeader->sample_precission)
    {
        Ipp32s iPitch = m_meCtx.m_iPitch;

        m_meCtx.m_pSrcPlanes8u[0] = m_meCtx.m_pSrcPlanes8u[0] -
                                     m_meCtx.MbWidth * 16 +
                                     iPitch * 16;
        if (AVS_CHROMA_420_FORMAT == m_meCtx.m_pSeqHeader->chroma_format)
        {
            m_meCtx.m_pSrcPlanes8u[1] = m_meCtx.m_pSrcPlanes8u[1] -
                                         m_meCtx.MbWidth * 8 +
                                         iPitch * 8;
            m_meCtx.m_pSrcPlanes8u[2] = m_meCtx.m_pSrcPlanes8u[2] -
                                         m_meCtx.MbWidth * 8 +
                                         iPitch * 8;
        }
        else
        {
            m_meCtx.m_pSrcPlanes8u[1] = m_meCtx.m_pSrcPlanes8u[1] -
                                         m_meCtx.MbWidth * 8 +
                                         iPitch * 16;
            m_meCtx.m_pSrcPlanes8u[2] = m_meCtx.m_pSrcPlanes8u[2] -
                                         m_meCtx.MbWidth * 8 +
                                         iPitch * 16;
        }
    }
} // void AVSME::FinalizeDisassembling(void)

} // namespace UMC

#endif // defined(UMC_ENABLE_AVS_VIDEO_ENCODER)
